https://mp.weixin.qq.com/s/jb3B9ltv3gvg2V4G8ESGZw

<!-- interface和type的区别 -->
https://mp.weixin.qq.com/s/0wjjAf-0ojqzht7PxSSYhg

类型别名type：类型别名不仅可以用来表示基本类型，还可以用来表示对象类型、联合类型、元组和交集。
接口是命名数据结构（例如对象）的另一种方式；与type 不同，interface仅限于描述对象类型。

<!-- 两者相似之处： -->
1.都可以描述 Object和Function，但语法不同

<!-- Type -->

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

<!-- Interface -->

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

2.二者都可以被继承

(另一个值得注意的是，接口(extends继承)和类型(&继承)别名并不互斥。类型别名可以继承接口，
反之亦然。只是在实现形式上，稍微有些差别。)
interface 继承 interface、interface 继承 type、type 继承 type、type 继承 interface
interface Student extends Person { stuNo: number }
type Student = Person & { stuNo: number }

3.实现 implements
（这种实现的意义在于通过implements关键字确保类实现了指定的接口或类型的结构，
以保证类中包含了接口或类型中定义的方法或属性。）
类可以实现interface 以及 type(除联合类型外)

interface ICat{
  setName(name:string): void;
}

class Cat implements ICat{
  setName(name:string):void{
      // todo
  }
}

上面提到了特殊情况，类无法实现联合类型, 是什么意思呢？

type Person = { name: string; } | { setName(name:string): void };

// 无法对联合类型Person进行实现
// error: A class can only implement an object type or intersection of object types with statically known members.
class Student implements Person {
  name= "张三";
  setName(name:string):void{
        // todo
    }
}

<!-- 二者区别 -->
1.类型别名type：类型别名不仅可以用来表示基本类型，还可以用来表示对象类型、联合类型、
元组和交集（type C = A & B, C 包含了A B类型所有属性）。
接口是命名数据结构（例如对象）的另一种方式；与type 不同，interface仅限于描述对象类型。


2.interface可以使用声明合并，而type使用声明合并是会报错的
interface Person { name: string }
interface Person { age: number }

let user: Person = {
    name: "Tolu",
    age: 0,
};

type Person { name: string }; 

// Error: 标识符“Person”重复。ts(2300)
type Person { age: number }

3.索引签名问题，type可以使用索引签名，inteface使用索引签名会报错
（interface具有声明合并的功能，他们在那一刻的类型并不是最终类型，
由于interfac可以进行声明合并，所以总有可能将新成员添加到同一个interface定义的类型上
）

Record<string,string>与{[key:string]：string}相同。
只有当该类型的所有属性都已知并且可以对照该索引签名进行检查时，才允许将子集分配给该索引签名类型。


interface propType{
  [key: string] : string
}

let props: propType

type dataType = {
  title: string
}
interface dataType1 {
  title: string
}
const data: dataType = {title: "订单页面"}
const data1: dataType1 = {title: "订单页面"}
props = data
// Error:类型“dataType1”不可分配给类型“propType”; 类型“dataType1”中缺少索引签名 
props = data1

对于 React 组件中 props及 state，使用 type ，这样能够保证使用组件的地方不能随意在上面添加属性。
如果有自定义需求，可通过 HOC二次封装。

编写三方库时使用interface，其更加灵活自动的类型合并可应对未知的复杂使用场景。
<!-- 泛型 -->
TypeScript 中的泛型是在函数、类和接口声明中使用方括号 <> 定义的，带有类型的占位符。
并且可以在使用函数、类或接口时指定形状。

这是一个例子。

function identity<T>(arg: T): T {
  return arg;
}

const result = identity<string>('Hello');
console.log(result); // Hello
